8. 抽象 Abstraction

抽象是一个十分重要的概念,分为对函数的抽象与对数据的抽象。

函数的抽象即指将某个计算过程封装在一个黑箱内加以使用。对一个过程进行抽象后,我们只关心其输入输出与功能,而不再关心其内部的实现逻辑。

如何为函数或变量命名与程序的正确性影响不大,但对于可读性十分重要。命名有一些可供参考的规范:

关于要对哪些表达式取值,可以遵循如下的建议:

抽象数据类型(Abstraction Data Type,ADT) 是另一种重要的抽象形式,其允许我们能够将复合对象作为整体进行操作,并将数据的表示方式与数据的操作方式通过函数分开。

在抽象数据类型中,新建一个抽象数据类型实例的函数被称作 构造函数(Constructor),从某个抽象数据类型实例中取出其某部份数据的函数被称作 选择函数(Selector)。构造函数与选择函数定义了这个抽象数据类型的行为。

数据的抽象一般存在多个层级,每个层级之间都存在由函数建立的 抽象屏障(Abstraction Barrier。维护抽象屏障是为了维持代码结构的规范性,实现在高层次上的抽象无需关注或对底层的实现细节做任何假定,而可以直接通过下层为上层提供的服务(即函数)实现自身的功能。同时,底层实现细节的修改也可以在不修改高层的情况下直接传导上来。

例如,假设我们要实现复数及其相关四则运算,我们可以建立这样的抽象结构:

抽象层级 在本层上实现的函数或功能
四则运算 add(), minus(), multiply(), divide(),...
构造与选择 complex_num(), get_real(),get_imaginary(),...
存储复数 通过 pair 存储复数的实部与虚部

当实现一个抽象数据结构时,我们需要确保构造函数与选择函数协作以确保这类数据在高层的函数中能进行正确的行为。我们通过数据的行为来判断该数据的类型。